<?php

declare(strict_types=1);

namespace app\controller\system\notify;

use app\BaseController;
use app\model\NotifyMessage;
use app\service\factory\ResponseFactory;
use app\service\notify\RecordService;
use app\validate\notify\RecordValidate;
use InvalidArgumentException;
use think\Response;
use Throwable;

class Record extends BaseController
{
    public function index(RecordService $recordService): Response
    {
        try {
            $page = max(1, (int) $this->request->param('page', 1));
            $pageSize = (int) $this->request->param('page_size', 20);
            $pageSize = $pageSize > 0 ? min($pageSize, 100) : 20;

            $filters = $this->request->only([
                'keyword',
                'status',
                'template_id',
            ], 'get');

            $paginator = $recordService->paginate($filters, $page, $pageSize);

            $items = $recordService->formatCollection($paginator->items(), false);

            return json(ResponseFactory::paginated(
                $items,
                (int) $paginator->total(),
                $page,
                $pageSize
            ));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function read(int $id, RecordService $recordService): Response
    {
        try {
            $message = $recordService->findById($id);
            if (!$message) {
                return json(ResponseFactory::error('通知不存在', 404));
            }

            return json(ResponseFactory::success($recordService->format($message)));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function markRead(int $id, RecordService $recordService): Response
    {
        try {
            $userId = (int) ($this->request->user_id ?? 0);
            if ($userId <= 0) {
                return json(ResponseFactory::error('未授权', 401));
            }

            $payload = $this->request->only([
                'recipient_id',
                'target_type',
                'target_id',
            ], 'post');

            $recipientId = isset($payload['recipient_id']) ? (int) $payload['recipient_id'] : null;
            $targetType = isset($payload['target_type']) && (string) $payload['target_type'] !== ''
                ? (string) $payload['target_type']
                : 'user';
            $targetId = isset($payload['target_id']) ? (int) $payload['target_id'] : $userId;
            if ($targetId <= 0) {
                $targetId = $userId;
            }
            if ($targetType === 'user') {
                $targetId = $userId;
            }

            $recipient = $recordService->markAsRead($id, $targetId, $targetType, $recipientId);

            return json(ResponseFactory::success(
                $recordService->formatRecipient($recipient),
                '通知已标记为已读'
            ));
        } catch (InvalidArgumentException $e) {
            return json(ResponseFactory::error($e->getMessage(), 422));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }

    public function resend(int $id, RecordService $recordService): Response
    {
        try {
            $message = NotifyMessage::find($id);
            if (!$message) {
                return json(ResponseFactory::error('通知不存在', 404));
            }

            $payload = $this->request->only([
                'recipient_ids',
            ], 'post');
            $payload['id'] = $id;

            $this->validate($payload, RecordValidate::class . '.resend');

            $recipientIds = $payload['recipient_ids'] ?? null;
            if (is_array($recipientIds)) {
                $recipientIds = array_values(array_unique(array_map('intval', $recipientIds)));
            } else {
                $recipientIds = null;
            }

            $resend = $recordService->resend($message, $recipientIds);

            return json(ResponseFactory::success($recordService->format($resend), '通知已加入重发队列'));
        } catch (InvalidArgumentException $e) {
            return json(ResponseFactory::error($e->getMessage(), 422));
        } catch (Throwable $e) {
            return json(ResponseFactory::error($e->getMessage(), $e->getCode() ?: 500));
        }
    }
}
